using System;
using System.Collections.Generic;
using Unity.Entities;

namespace Gj
{
    public class AiLogicService : GameService
    {
        public static AiLogicService single;

        public List<Logic> list = new();

        private readonly Dictionary<int, object[]> map = new();
        public List<int> tmp = new();

        static AiLogicService()
        {
            single = new AiLogicService();
        }

        public void OnDestroy()
        {
            single = new AiLogicService();
        }

        public void OnInit()
        {
        }

        public void OnUpdate()
        {
            
        }

        public void SetObjects(object[] arr)
        {
            foreach (object[] obj in arr) SetObject(obj);
        }

        public void SetObject(object[] obj)
        {
            map.Add(Convert.ToInt32(obj[(byte)OBJECT_INFO.ID]), obj);
        }

        public ObjectInfo GetObject(int objectId)
        {
            return new ObjectInfo(map[objectId]);
        }

        public Logic Get(Entity e)
        {
            var manager = ObjectService.EntityManager;
            if (manager.HasComponent<EntityData>(e)) return list[manager.GetComponentData<EntityData>(e).index];

            return null;
        }

        private int GetIndex()
        {
            if (tmp.Count > 0)
            {
                var i = tmp[0];
                tmp.RemoveAt(0);
                return i;
            }

            return list.Count;
        }

        private int Add(Logic element)
        {
            var i = GetIndex();
            if (i == list.Count)
                list.Add(element);
            else
                list[i] = element;

            return i;
        }

        private void Remove(Logic element)
        {
            var i = element.GetIndex();
            if (list.Count > i && i >= 0) list[i] = null;
            tmp.Add(i);
        }

        public T MakeLogic<T>(string name)
        {
            var baseLogic = ObjectService.single.MakeLogic(name).GetComponent<BaseLogic>();
            baseLogic.GameObject.SetActive(true);
            baseLogic.Init(Add(baseLogic));
            return baseLogic.GameObject.GetComponent<T>();
        }

        public T MakeLogicTmp<T>(string name)
        {
            var baseLogic = ObjectService.single.MakeLogic(name).GetComponent<BaseLogic>();
            baseLogic.GameObject.SetActive(true);
            baseLogic.Init(0);
            return baseLogic.GameObject.GetComponent<T>();
        }

        public void DestroyLogic(BaseLogic element)
        {
            Remove(element);
            element.GameObject.SetActive(false);
            ObjectService.single.DestroyObj(element.gameObject);
        }
    }
}